'use strict';

/**
 * 部门模型
 * @param app
 */
module.exports = app => {
  const { STRING, INTEGER, BOOLEAN, DATE, BIGINT } = app.Sequelize;

  const Department = app.model.define('sys_departments', {
    id: {
      type: BIGINT,
      primaryKey: true,
      comment: '部门ID',
    },
    name: {
      type: STRING(50),
      allowNull: false,
      comment: '部门名称',
    },
    parentId: {
      type: BIGINT,
      allowNull: true,
      defaultValue: 0,
      comment: '父部门ID，0表示顶级部门',
      field: 'parent_id',
    },
    description: {
      type: STRING(255),
      allowNull: true,
      comment: '部门描述',
      field: 'description',
    },
    sort: {
      type: INTEGER,
      allowNull: true,
      defaultValue: 0,
      comment: '排序号',
    },
    status: {
      type: BOOLEAN,
      defaultValue: true,
      comment: '状态：true启用，false禁用',
    },
    createTime: {
      type: DATE,
      allowNull: false,
      comment: '创建时间',
      field: 'create_time',
      defaultValue: app.Sequelize.NOW,
    },
    updateTime: {
      type: DATE,
      allowNull: false,
      comment: '更新时间',
      field: 'update_time',
      defaultValue: app.Sequelize.NOW,
    },
  });

  // 关联关系
  Department.associate = function() {
    // 自关联，父部门
    app.model.Department.belongsTo(app.model.Department,
      {
        foreignKey: 'parentId',
        as: 'parent',
        targetKey: 'id',
      });

    // 自关联，子部门
    app.model.Department.hasMany(app.model.Department,
      {
        foreignKey: 'parentId',
        as: 'children',
        sourceKey: 'id',
      });

    // 关联用户
    app.model.Department.hasMany(app.model.User,
      {
        foreignKey: 'departmentId',
        as: 'users',
      });
  };

  // 在创建前生成雪花ID
  Department.beforeCreate((department) => {
    const SnowflakeUtil = require('../utils/snowflake');
    department.id = SnowflakeUtil.generateSnowflakeId();
  });

  // 自定义toJSON方法，避免字段重复
  Department.prototype.toJSON = function() {

    const values = Object.assign({}, this.get());

    // 移除重复的下划线字段
    delete values.create_time;
    delete values.update_time;

    return values;

  };

  return Department;
};
